package ${s.pkg};

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;

import la.cplus.common.constants.CommonConstants;
import la.cplus.common.fsm.UnknownStateException;

public enum ${s.name}Status {

#foreach( ${f} in ${s.stats} )
    ${f.name}(CommonConstants.${s.name}Status.${f.name}, "${f.name}"),
#end
;

    private final Integer status;
    private final String description;

    public Integer getStatus() {
        return status;
    }

    public String getDescription() {
        return description;
    }

    ${s.name}Status(Integer status, String description) {
        this.status = status;
        this.description = description;
    }

    public static ${s.name}Status get${s.name}Status(Integer status) {
        for (${s.name}Status s : ${s.name}Status.values()) {
        if (s.getStatus().compareTo(status) == 0)
            return s;
        }
        throw new UnknownStateException();
    }
    
    /**
     * get the previous status of ${s.name}
     * 
     * @param
     * @return
     */
    public ${s.name}Status getPreviousStatus() {
        ${s.name}Status previous = null;
        ${s.name}Status[] statuss = ${s.name}Status.values();
        Arrays.sort(statuss, new Comparator<${s.name}Status>() {
        @Override
        public int compare(${s.name}Status o1, ${s.name}Status o2) {
            return o1.getStatus().compareTo(o2.getStatus());
        }
        });
        for (int i = 0; i < statuss.length; i++) {
        if (i > 0 && this == statuss[i]) {
            previous = statuss[i - 1];
            break;
        }
        }
        return previous;
    }

    /**
     * get the next status of ${s.name}
     * 
     * @param
     * @return
     */
    public ${s.name}Status getNextStatus() {
        ${s.name}Status next = null;
        ${s.name}Status[] statuss = ${s.name}Status.values();
        Arrays.sort(statuss, new Comparator<${s.name}Status>() {
        @Override
        public int compare(${s.name}Status o1, ${s.name}Status o2) {
            return o2.getStatus().compareTo(o1.getStatus());
        }
        });
        for (int i = 0; i < statuss.length; i++) {
        if (i > 0 && this == statuss[i]) {
            next = statuss[i - 1];
            break;
        }
        }
        return next;
    }

    /**
     * get a status collection
     * 
     * @param min
     * @param includeMin
     * @param max
     * @param includeMax
     * @return
     */
    public static Integer[] getStatusRange(${s.name}Status min, boolean includeMin, ${s.name}Status max, boolean includeMax) {
        ${s.name}Status[] statuss = ${s.name}Status.values();
        Arrays.sort(statuss, new Comparator<${s.name}Status>() {
        @Override
        public int compare(${s.name}Status o1, ${s.name}Status o2) {
            return o1.getStatus().compareTo(o2.getStatus());
        }
        });
        Set<Integer> list = new HashSet<Integer>();
        for (int i = 0; i < statuss.length; i++) {
        ${s.name}Status current = statuss[i];
        if (min != null) {
            switch (current.getStatus().compareTo(min.getStatus())) {
            case 0:
            if (includeMin) {
                list.add(current.getStatus());
            }
            break;
            case 1:
            if (max != null) {
                switch (current.getStatus().compareTo(max.getStatus())) {
                case 0:
                if (includeMax) {
                    list.add(current.getStatus());
                }
                break;

                case -1:
                list.add(current.getStatus());
                break;
                }
            } else {
                list.add(current.getStatus());
            }
            break;
            }
        } else if( max != null){
            switch (current.getStatus().compareTo(max.getStatus())) {
            case 0:
            if (includeMax) {
                list.add(current.getStatus());
            }
            break;

            case -1:
            list.add(current.getStatus());
            break;
            }        
        }else {
            list.add(current.getStatus());
        }
        }
        return list.toArray(new Integer[0]);
    }	

}
